package ScannerParser;

import java.io.*;
import goldengine.*;

/*
 * Licensed Material - Property of Matthew Hawkins (hawkini@4email.net) 
 */
public class DecafOld implements GPMessageConstants {

    private interface SymbolConstants {

        final int SYMBOL_EOF = 0;  // (EOF)
        final int SYMBOL_ERROR = 1;  // (Error)
        final int SYMBOL_WHITESPACE = 2;  // (Whitespace)
        final int SYMBOL_MINUS = 3;  // '-'
        final int SYMBOL_EXCLAM = 4;  // '!'
        final int SYMBOL_EXCLAMEQ = 5;  // '!='
        final int SYMBOL_PERCENT = 6;  // '%'
        final int SYMBOL_AMPAMP = 7;  // '&&'
        final int SYMBOL_LPARAN = 8;  // '('
        final int SYMBOL_RPARAN = 9;  // ')'
        final int SYMBOL_TIMES = 10;  // '*'
        final int SYMBOL_COMMA = 11;  // ','
        final int SYMBOL_DOT = 12;  // '.'
        final int SYMBOL_DIV = 13;  // '/'
        final int SYMBOL_SEMI = 14;  // ';'
        final int SYMBOL_LBRACKET = 15;  // '['
        final int SYMBOL_RBRACKET = 16;  // ']'
        final int SYMBOL_LBRACE = 17;  // '{'
        final int SYMBOL_PIPEPIPE = 18;  // '||'
        final int SYMBOL_RBRACE = 19;  // '}'
        final int SYMBOL_PLUS = 20;  // '+'
        final int SYMBOL_LT = 21;  // '<'
        final int SYMBOL_LTEQ = 22;  // '<='
        final int SYMBOL_EQ = 23;  // '='
        final int SYMBOL_EQEQ = 24;  // '=='
        final int SYMBOL_GT = 25;  // '>'
        final int SYMBOL_GTEQ = 26;  // '>='
        final int SYMBOL_BOOLEAN = 27;  // boolean
        final int SYMBOL_CHAR = 28;  // char
        final int SYMBOL_CLASS = 29;  // class
        final int SYMBOL_ELSE = 30;  // else
        final int SYMBOL_FALSE = 31;  // false
        final int SYMBOL_ID = 32;  // id
        final int SYMBOL_IF = 33;  // if
        final int SYMBOL_INT = 34;  // int
        final int SYMBOL_NUM = 35;  // num
        final int SYMBOL_PROGRAM = 36;  // Program
        final int SYMBOL_QUOTE = 37;  // quote
        final int SYMBOL_RETURN = 38;  // return
        final int SYMBOL_STRUCT = 39;  // struct
        final int SYMBOL_TRUE = 40;  // true
        final int SYMBOL_VOID = 41;  // void
        final int SYMBOL_WHILE = 42;  // while
        final int SYMBOL_ARG = 43;  // <arg>
        final int SYMBOL_ARITH_OP = 44;  // <arith_op>
        final int SYMBOL_BLOCK = 45;  // <block>
        final int SYMBOL_BOOL_LITERAL = 46;  // <bool_literal>
        final int SYMBOL_CHAR_LITERAL = 47;  // <char_literal>
        final int SYMBOL_COND_OP = 48;  // <cond_op>
        final int SYMBOL_DECLARATION = 49;  // <declaration>
        final int SYMBOL_ELSEORNOT = 50;  // <elseOrNot>
        final int SYMBOL_EQ_OP = 51;  // <eq_op>
        final int SYMBOL_EXPRESSION = 52;  // <expression>
        final int SYMBOL_EXPRESSION2 = 53;  // <expression2>
        final int SYMBOL_EXPRESSIONORNOT = 54;  // <expressionOrNot>
        final int SYMBOL_INT_LITERAL = 55;  // <int_literal>
        final int SYMBOL_KLEENARG = 56;  // <kleenArg>
        final int SYMBOL_KLEENDECLARATION = 57;  // <kleenDeclaration>
        final int SYMBOL_KLEENPARAMETERS = 58;  // <kleenParameters>
        final int SYMBOL_KLEENSTATEMENT = 59;  // <kleenStatement>
        final int SYMBOL_KLEENVARDECLARATION = 60;  // <kleenVarDeclaration>
        final int SYMBOL_LITERAL = 61;  // <literal>
        final int SYMBOL_LOCATION = 62;  // <location>
        final int SYMBOL_LOCATIONORNOT = 63;  // <locationOrNot>
        final int SYMBOL_LOCATIONSUBGROUP = 64;  // <locationSubGroup>
        final int SYMBOL_LOCATIONSUBGROUP2 = 65;  // <locationSubGroup2>
        final int SYMBOL_METHODCALL = 66;  // <methodCall>
        final int SYMBOL_METHODDECLARATION = 67;  // <methodDeclaration>
        final int SYMBOL_METHODDECLARATIONSUBG = 68;  // <methodDeclarationSubG>
        final int SYMBOL_METHODTYPE = 69;  // <methodType>
        final int SYMBOL_NUEVA = 70;  // <nueva>
        final int SYMBOL_NUEVA2 = 71;  // <nueva2>
        final int SYMBOL_OP = 72;  // <op>
        final int SYMBOL_PARAMETERS = 73;  // <parameters>
        final int SYMBOL_PARAMETERSSUBG = 74;  // <parametersSubG>
        final int SYMBOL_PARAMETERTYPE = 75;  // <parameterType>
        final int SYMBOL_PROGRAM2 = 76;  // <program>
        final int SYMBOL_REL_OP = 77;  // <rel_op>
        final int SYMBOL_STATEMENT = 78;  // <statement>
        final int SYMBOL_STRUCTDECLARATION = 79;  // <structDeclaration>
        final int SYMBOL_VARDECLARATION = 80;  // <varDeclaration>
        final int SYMBOL_VARDECLARATIONSUBG = 81;  // <varDeclarationSubG>
        final int SYMBOL_VARTYPE = 82;  // <varType>
        final int SYMBOL_VARTYPESUBG = 83;  // <varTypeSubG>
    };

    private interface RuleConstants {

        final int RULE_PROGRAM_CLASS_PROGRAM_LBRACE_RBRACE = 0;  // <program> ::= class Program '{' <kleenDeclaration> '}'
        final int RULE_KLEENDECLARATION = 1;  // <kleenDeclaration> ::= <declaration> <kleenDeclaration>
        final int RULE_KLEENDECLARATION2 = 2;  // <kleenDeclaration> ::=
        final int RULE_DECLARATION = 3;  // <declaration> ::= <structDeclaration>
        final int RULE_DECLARATION2 = 4;  // <declaration> ::= <nueva>
        final int RULE_NUEVA_ID = 5;  // <nueva> ::= <methodType> id <nueva2>
        final int RULE_NUEVA_ID2 = 6;  // <nueva> ::= <varTypeSubG> id <varDeclarationSubG>
        final int RULE_NUEVA2 = 7;  // <nueva2> ::= <varDeclarationSubG>
        final int RULE_NUEVA22 = 8;  // <nueva2> ::= <methodDeclarationSubG>
        final int RULE_KLEENVARDECLARATION = 9;  // <kleenVarDeclaration> ::= <varDeclaration> <kleenVarDeclaration>
        final int RULE_KLEENVARDECLARATION2 = 10;  // <kleenVarDeclaration> ::=
        final int RULE_VARDECLARATION_ID = 11;  // <varDeclaration> ::= <varType> id <varDeclarationSubG>
        final int RULE_VARDECLARATIONSUBG_SEMI = 12;  // <varDeclarationSubG> ::= ';'
        final int RULE_VARDECLARATIONSUBG_LBRACKET_NUM_RBRACKET_SEMI = 13;  // <varDeclarationSubG> ::= '[' num ']' ';'
        final int RULE_STRUCTDECLARATION_STRUCT_ID_LBRACE_RBRACE = 14;  // <structDeclaration> ::= struct id '{' <kleenVarDeclaration> '}'
        final int RULE_VARTYPE = 15;  // <varType> ::= <methodType>
        final int RULE_VARTYPE_STRUCT_ID = 16;  // <varType> ::= struct id
        final int RULE_VARTYPE2 = 17;  // <varType> ::= <structDeclaration>
        final int RULE_VARTYPESUBG_STRUCT_ID = 18;  // <varTypeSubG> ::= struct id
        final int RULE_VARTYPESUBG = 19;  // <varTypeSubG> ::= <structDeclaration>
        final int RULE_METHODDECLARATION_ID_LPARAN_RPARAN = 20;  // <methodDeclaration> ::= <methodType> id '(' <kleenParameters> ')' <block>
        final int RULE_METHODDECLARATIONSUBG_LPARAN_RPARAN = 21;  // <methodDeclarationSubG> ::= '(' <kleenParameters> ')' <block>
        final int RULE_METHODTYPE_INT = 22;  // <methodType> ::= int
        final int RULE_METHODTYPE_CHAR = 23;  // <methodType> ::= char
        final int RULE_METHODTYPE_BOOLEAN = 24;  // <methodType> ::= boolean
        final int RULE_METHODTYPE_VOID = 25;  // <methodType> ::= void
        final int RULE_KLEENPARAMETERS_COMMA = 26;  // <kleenParameters> ::= <parameters> ',' <kleenParameters>
        final int RULE_KLEENPARAMETERS = 27;  // <kleenParameters> ::= <parameters>
        final int RULE_KLEENPARAMETERS2 = 28;  // <kleenParameters> ::=
        final int RULE_PARAMETERS_ID = 29;  // <parameters> ::= <parameterType> id <parametersSubG>
        final int RULE_PARAMETERSSUBG_LBRACKET_RBRACKET = 30;  // <parametersSubG> ::= '[' ']'
        final int RULE_PARAMETERSSUBG = 31;  // <parametersSubG> ::=
        final int RULE_PARAMETERTYPE_INT = 32;  // <parameterType> ::= int
        final int RULE_PARAMETERTYPE_CHAR = 33;  // <parameterType> ::= char
        final int RULE_PARAMETERTYPE_BOOLEAN = 34;  // <parameterType> ::= boolean
        final int RULE_BLOCK_LBRACE_RBRACE = 35;  // <block> ::= '{' <kleenVarDeclaration> <kleenStatement> '}'
        final int RULE_KLEENSTATEMENT = 36;  // <kleenStatement> ::= <statement> <kleenStatement>
        final int RULE_KLEENSTATEMENT2 = 37;  // <kleenStatement> ::=
        final int RULE_STATEMENT_IF_LPARAN_RPARAN = 38;  // <statement> ::= if '(' <expression> ')' <block> <elseOrNot>
        final int RULE_STATEMENT_WHILE_LPARAN_RPARAN = 39;  // <statement> ::= while '(' <expression> ')' <block>
        final int RULE_STATEMENT_RETURN_SEMI = 40;  // <statement> ::= return <expressionOrNot> ';'
        final int RULE_STATEMENT_SEMI = 41;  // <statement> ::= <methodCall> ';'
        final int RULE_STATEMENT = 42;  // <statement> ::= <block>
        final int RULE_STATEMENT_EQ = 43;  // <statement> ::= <location> '=' <expression>
        final int RULE_STATEMENT_SEMI2 = 44;  // <statement> ::= <expressionOrNot> ';'
        final int RULE_ELSEORNOT_ELSE = 45;  // <elseOrNot> ::= else <block>
        final int RULE_ELSEORNOT = 46;  // <elseOrNot> ::=
        final int RULE_LOCATION = 47;  // <location> ::= <locationSubGroup> <locationOrNot>
        final int RULE_LOCATIONSUBGROUP_ID = 48;  // <locationSubGroup> ::= id <locationSubGroup2>
        final int RULE_LOCATIONSUBGROUP2_LBRACKET_RBRACKET = 49;  // <locationSubGroup2> ::= '[' <expression> ']'
        final int RULE_LOCATIONSUBGROUP2 = 50;  // <locationSubGroup2> ::=
        final int RULE_LOCATIONORNOT_DOT = 51;  // <locationOrNot> ::= '.' <location>
        final int RULE_LOCATIONORNOT = 52;  // <locationOrNot> ::=
        final int RULE_EXPRESSIONORNOT = 53;  // <expressionOrNot> ::= <expression>
        final int RULE_EXPRESSIONORNOT2 = 54;  // <expressionOrNot> ::=
        final int RULE_EXPRESSION = 55;  // <expression> ::= <location>
        final int RULE_EXPRESSION2 = 56;  // <expression> ::= <methodCall>
        final int RULE_EXPRESSION3 = 57;  // <expression> ::= <literal>
        final int RULE_EXPRESSION4 = 58;  // <expression> ::= <expression2>
        final int RULE_EXPRESSION_MINUS = 59;  // <expression> ::= '-' <expression>
        final int RULE_EXPRESSION_EXCLAM = 60;  // <expression> ::= '!' <expression>
        final int RULE_EXPRESSION_LPARAN_RPARAN = 61;  // <expression> ::= '(' <expression> ')'
        final int RULE_EXPRESSION22 = 62;  // <expression2> ::= <expression> <op> <expression>
        final int RULE_METHODCALL_ID_LPARAN_RPARAN = 63;  // <methodCall> ::= id '(' <kleenArg> ')'
        final int RULE_KLEENARG_COMMA = 64;  // <kleenArg> ::= <arg> ',' <kleenArg>
        final int RULE_KLEENARG = 65;  // <kleenArg> ::= <arg>
        final int RULE_KLEENARG2 = 66;  // <kleenArg> ::=
        final int RULE_ARG = 67;  // <arg> ::= <expression>
        final int RULE_OP = 68;  // <op> ::= <arith_op>
        final int RULE_OP2 = 69;  // <op> ::= <rel_op>
        final int RULE_OP3 = 70;  // <op> ::= <eq_op>
        final int RULE_OP4 = 71;  // <op> ::= <cond_op>
        final int RULE_ARITH_OP_PLUS = 72;  // <arith_op> ::= '+'
        final int RULE_ARITH_OP_MINUS = 73;  // <arith_op> ::= '-'
        final int RULE_ARITH_OP_TIMES = 74;  // <arith_op> ::= '*'
        final int RULE_ARITH_OP_DIV = 75;  // <arith_op> ::= '/'
        final int RULE_ARITH_OP_PERCENT = 76;  // <arith_op> ::= '%'
        final int RULE_REL_OP_LT = 77;  // <rel_op> ::= '<'
        final int RULE_REL_OP_GT = 78;  // <rel_op> ::= '>'
        final int RULE_REL_OP_LTEQ = 79;  // <rel_op> ::= '<='
        final int RULE_REL_OP_GTEQ = 80;  // <rel_op> ::= '>='
        final int RULE_EQ_OP_EQEQ = 81;  // <eq_op> ::= '=='
        final int RULE_EQ_OP_EXCLAMEQ = 82;  // <eq_op> ::= '!='
        final int RULE_COND_OP_AMPAMP = 83;  // <cond_op> ::= '&&'
        final int RULE_COND_OP_PIPEPIPE = 84;  // <cond_op> ::= '||'
        final int RULE_LITERAL = 85;  // <literal> ::= <int_literal>
        final int RULE_LITERAL2 = 86;  // <literal> ::= <char_literal>
        final int RULE_LITERAL3 = 87;  // <literal> ::= <bool_literal>
        final int RULE_INT_LITERAL_NUM = 88;  // <int_literal> ::= num
        final int RULE_CHAR_LITERAL_QUOTE_CHAR_QUOTE = 89;  // <char_literal> ::= quote char quote
        final int RULE_BOOL_LITERAL_TRUE = 90;  // <bool_literal> ::= true
        final int RULE_BOOL_LITERAL_FALSE = 91;  // <bool_literal> ::= false
        
    };
    private static BufferedReader buffR;

    /***************************************************************
     * This class will run the engine, and needs a file called config.dat
     * in the current directory. This file should contain two lines,
     * The first should be the absolute path name to the .cgt file, the second
     * should be the source file you wish to parse.
     * @param args Array of arguments.
     ***************************************************************/
    public static SyntaxTree CreateTree() {
        String textToParse = "", compiledGrammar = "";
        SyntaxTree tree = null;
        boolean temp = true;

        try {
            buffR = new BufferedReader(new FileReader(new File("/home/jefoutta/Projects/jefoxc2/jefoxc2/src/ScannerParser/config.dat")));
            compiledGrammar = buffR.readLine();
            textToParse = buffR.readLine();

            buffR.close();
        } catch (FileNotFoundException fnfex) {
            System.out.println("Config File was not found.\n\n"
                    + "Please place it in the current directory.");
            System.exit(1);
        } catch (IOException ioex) {
            System.out.println("An error occured while reading config.dat.\n\n"
                    + "Please re-try ensuring the file can be read.");
            System.exit(1);
        }

        GOLDParser parser = new GOLDParser();

        try {
            parser.loadCompiledGrammar(compiledGrammar);
            parser.openFile(textToParse);
        } catch (ParserException parse) {
            System.out.println("**PARSER ERROR**\n" + parse.toString());
            System.exit(1);
        }

        boolean done = false;
        int response = -1;

        while (!done) {
            try {
                response = parser.parse();
            } catch (ParserException parse) {
                System.out.println("**PARSER ERROR**\n" + parse.toString());
                System.exit(1);
            }

            switch (response) {
                case gpMsgTokenRead:
                    /* A token was read by the parser. The Token Object can be accessed
                    through the CurrentToken() property:  Parser.CurrentToken */
                    break;

                case gpMsgReduction:
                    /* This message is returned when a rule was reduced by the parse engine.
                    The CurrentReduction property is assigned a Reduction object
                    containing the rule and its related tokens. You can reassign this
                    property to your own customized class. If this is not the case,
                    this message can be ignored and the Reduction object will be used
                    to store the parse tree.  */

                    

                    //Parser.Reduction = //Object you created to store the rule

                    // ************************************** log file
                    System.out.println("gpMsgReduction");
                    Reduction myRed = parser.currentReduction();
                    /*if (temp) {
                        tree = new Tree(myRed.getParentRule().getText());
                        temp = false;
                    } else {
                        tree.addInverter(new Tree(myRed.getParentRule().getText()));
                    }*/
                    System.out.println(myRed.getParentRule().getText());
                    // ************************************** end log

                    break;

                case gpMsgAccept:
                    /* The program was accepted by the parsing engine */

                    // ************************************** log file
                    System.out.println("gpMsgAccept");
                    // ************************************** end log
                    System.out.println("Aqui empieza___________________________________");
                    tree = new SyntaxTree(parser.currentReduction());
                    System.out.println("Aqui termina____________________________________");

                    //*************************************** tree construction
                    //Tree.setParser(parser);
                    //tree = new Tree(parser.currentReduction().getParentRule());

                    done = true;

                    break;

                case gpMsgLexicalError:
                    /* Place code here to handle a illegal or unrecognized token
                    To recover, pop the token from the stack: Parser.PopInputToken */

                    // ************************************** log file
                    System.out.println("gpMsgLexicalError");
                    // ************************************** end log

                    parser.popInputToken();

                    break;

                case gpMsgNotLoadedError:
                    /* Load the Compiled Grammar Table file first. */

                    // ************************************** log file
                    System.out.println("gpMsgNotLoadedError");
                    // ************************************** end log

                    done = true;

                    break;

                case gpMsgSyntaxError:
                    /* This is a syntax error: the source has produced a token that was
                    not expected by the LALR State Machine. The expected tokens are stored
                    into the Tokens() list. To recover, push one of the
                    expected tokens onto the parser's input queue (the first in this case):
                    You should limit the number of times this type of recovery can take
                    place. */

                    done = true;

                    Token theTok = parser.currentToken();
                    System.out.println("Token not expected: " + (String) theTok.getData());

                    // ************************************** log file
                    System.out.println("gpMsgSyntaxError");
                    // ************************************** end log

                    break;

                case gpMsgCommentError:
                    /* The end of the input was reached while reading a comment.
                    This is caused by a comment that was not terminated */

                    // ************************************** log file
                    System.out.println("gpMsgCommentError");
                    // ************************************** end log

                    done = true;

                    break;

                case gpMsgInternalError:
                    /* Something horrid happened inside the parser. You cannot recover */

                    // ************************************** log file
                    System.out.println("gpMsgInternalError");
                    // ************************************** end log

                    done = true;

                    break;
            }
        }
        try {
            parser.closeFile();
        } catch (ParserException parse) {
            System.out.println("**PARSER ERROR**\n" + parse.toString());
            System.exit(1);
        }
        return tree;
    }
}
